package com.dsg.util;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.dsg.support.TxtProperty;
import com.powerbridge.core.util.BeanKit;
import com.powerbridge.core.util.toolbox.CollectionUtil;
import com.powerbridge.core.util.toolbox.StringUtil;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.lang.reflect.Field;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @program: erp
 * @description: 导出文件的工具类
 * @author: lironglai
 * @create: 2020-08-19 21:54
 */
@Slf4j
public class ExportTextUtil {


    private List<List<Object>> lists = new ArrayList<>();

    /**
     * @param clazz
     * @param list
     * @throws Exception
     */
    public void write(Class clazz, List list) throws Exception {
        Field[] fields = clazz.getDeclaredFields();
        Map<String, TxtProperty> txtPropertyMap = new LinkedHashMap<>();
        Map<String, Field> fileMap = new LinkedHashMap<>();
        for (Field field : fields) {
            TxtProperty txtProperty = field.getAnnotation(TxtProperty.class);
            if (txtProperty != null) {
                txtPropertyMap.put(field.getName(), txtProperty);
                fileMap.put(field.getName(), field);
            }
        }
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String pattern = "EEE MMM dd HH:mm:ss zzz yyyy";
        SimpleDateFormat df2 = new SimpleDateFormat(pattern, Locale.US);
        List<String> errorList = new ArrayList<>();
        for (Object data : list) {
            List<Object> list1 = new ArrayList<>();
            for (String key : fileMap.keySet()) {
                Object value = BeanKit.getProperty(data, key);
                String type = fileMap.get(key).getType().getTypeName();
                String txt = value == null ? "" : value.toString();
                //日期格式化
                if (StringUtil.isNotEmpty(txtPropertyMap.get(key).format())) {
                    df = new SimpleDateFormat(txtPropertyMap.get(key).format());
                }
                //字段保留长度
                int size = txtPropertyMap.get(key).size();
                int length = txt.length();
                switch (type) {
                    case "java.math.BigDecimal":
                    case "java.lang.Integer":
                    case "java.lang.Double":
                    case "java.lang.Float":
                        if (StringUtil.isNotEmpty(txt)) {
                            NumberFormat nf = NumberFormat.getInstance();
                            // 设置此格式中不使用分组
                            nf.setGroupingUsed(false);
                            // 设置数的小数部分所允许的最大位数。
                            nf.setMaximumFractionDigits(2);
                            txt = nf.format(Double.parseDouble(txt));
                            Double tmp = Double.parseDouble(txt);
                            txt = String.format("%0" + size + "d", Math.abs(tmp.intValue()));
                        } else {
                            txt = String.format("%0" + size + "d", 0);
                        }
                        list1.add(txt);
                        break;
                    case "java.util.Date":
                        //获取时间的String 值 转成Date。Date格式化为指定格式
                        if (StringUtil.isNotEmpty(txt)) {
                            Date date = df2.parse(txt);
                            txt = df.format(date);
                            txt = setTxtLength(size, length, txt, errorList);
                        }
                        list1.add(txt);
                        break;
                    default:
                        if (StringUtil.isEmpty(txt)){
                            txt = " ";
                        }
                        txt = setTxtLength(size, length, txt, errorList);
                        list1.add(txt);
                        break;
                }
            }
            lists.add(list1);
        }
        if (CollectionUtil.isNotEmpty(errorList)) {
            throw new RRException(errorList.toString());
        }
    }

    /**
     * 导出文本文件
     *
     * @param response
     * @param fileName
     */
    public void writeToTxt(HttpServletResponse response, String fileName) {
        //设置响应的字符集
        response.setCharacterEncoding("utf-8");
        //设置响应内容的类型
        response.setContentType("text/plain");
        //设置文件的名称和格式
        response.addHeader(
                "Content-Disposition",
                "attachment; filename="
                        + FileUtil.genAttachmentFileName(fileName + "_", "JSON_FOR_UCC_")
                        + MessageFormat.format("{0,date,yyyy-MM-dd HH:mm:ss}", new Object[]{Calendar.getInstance().getTime()})
                        + ".txt");
        //通过后缀可以下载不同的文件格式
        BufferedOutputStream buff = null;
        ServletOutputStream outStr = null;
        try {
            outStr = response.getOutputStream();
            buff = new BufferedOutputStream(outStr);
            StringBuilder txt = new StringBuilder();
            for (List<Object> list : lists) {
                txt.setLength(0);
                for (Object obj : list) {
                    txt = txt.append(obj.toString());
                }
                buff.write(txt.toString().getBytes("UTF-8"));
                buff.write("\r\n".getBytes());
            }
            buff.flush();
            buff.close();
        } catch (Exception e) {
            log.error("導出文件出錯，e:{}", e);
        } finally {
            try {
                buff.close();
                outStr.close();
            } catch (Exception e) {
                log.error("關閉流對象出錯 e:{}", e);
            }
        }
    }

    /**
     * 如果字符串对象为 null，则返回空字符串，否则返回去掉字符串前后空格的字符串
     *
     * @param str
     * @return
     */
    public String delNull(String str) {
        String returnStr = "";
        if (StringUtils.isNotBlank(str)) {
            returnStr = str.trim();
        }
        return returnStr;
    }


    private String setTxtLength(int size, int length, String txt, List<String> errorList) {
        if (size > 0) {
            if (length <= size) {
                txt = String.format("%-" + size + "s", txt);
            } else {
                errorList.add(String.format("%s長度不能超過%s", txt, size));
            }
        }
        return txt;
    }
}
